DATA SEGMENT
;******** 控制类 ********

 HANGID DB 5  ; 行号
 POSITION DB 0  ; 字母出现的起始列数 
 WHICH DB 0  ; SI指针的定位
 TOTAL DB 0  ; MODE1下落字母的总数或者是MODE2按键的次数
 DELAYTIME DB 03H ; 下落延时（难度控制）
 BLANK DB ' ', 0H ; 覆盖用的空格
 OUTFLAG DB 0  ; 记录退出选项
 DIFFICULTYFLAG DB 0 ; 难度选项
 MODEFLAG DB 0  ; 模式选项

;******** 数据类 ********
 ARTICLE DB 'Human'
 LIST DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZCNHNJLJKHOGPOINGLHLKJIJNGM'
 TIPS1 DB 'I', 0EH, 'N', 0EH, 'S', 0EH, 'T', 0EH, 'R', 0EH, 'U', 0EH, 'C', 0EH, 'T', 0EH, 'I', 0EH, 'O', 0EH, 'N', 0EH, ':', 0EH
 TIPS2 DB 'D',0EH, 'I',0EH, 'F',0EH,'F',0EH,'I',0EH,'C',0EH,'U',0EH,'L',0EH,'T',0EH,'Y',0EH,' ',0EH,'S',0EH,'E',0EH,'L',0EH,'E',0EH,'C',0EH,'T',0EH
 TIPS3 DB 'MODE SELECT'
 TIPS4 DB 'DON''T USE BACKSPACE OR ARROWS, JUST TYPE THE LETTERS!!'
 TIPS5 DB 'PRESS ESC TO QUIT'
 CONTENT DB 'MODE1: SPEED TYPING   MODE2: EXERCISE TYPING'
 STR1 DB 'YOU HAVE SELECTED ', '$'
 STR2 DB '  PRESS ANYKEY TO START GAME!', '$'
 STR3 DB 'GAME FINISHED! YOUR RANK IS '
 STR4 DB 'PRESS ESC TO DIPLAY THE MENU'
 STR5 DB 'START TIME: '
 STR6 DB 'ACCURACY: '
 STR7 DB 'END TIME: '
 MAX DB '100 %'
 INFO DB 'VERSION: 0.2   PRODUCED BY: Sure'
 NORMAL DB 'NORMAL' 
 HARD DB ' HARD '
 MODE1 DB 'MODE1'
 MODE2 DB 'MODE2'
 YESQUIT DB ' I WANT TO QUIT!! '
 NOTQUIT DB 'CONTINUE TO PLAY!!'
 ENDL DB 0DH, 0AH, '$'
 RANK DB 0
 SCORE DB 'SCORE:'
 HIT DB 'HIT:'
 MISS DB 'MISS:'
 SCORENUMBER DB 0  ; 得分
 HITNUMBER DB 0   
 MISSNUMBER DB 0   
 TEMP DB 2 DUP(0)  ; 暂存计算所得的成绩（10进制）
 HOUR DB 0   ; 存储小时
 MINUTE DB 0   ; 存储分钟
 SECOND DB 0   ; 存储秒
 THANKS DB 'THANK YOU FOR PLAYING! ^O^'
 JIESHU DB 'PRESS ANY KEY TO QUIT...'
DATA ENDS

STACK SEGMENT PARA STACK
 DW 100 DUP(0)
STACK ENDS

CODE SEGMENT
 ASSUME CS:CODE, SS:STACK, DS:DATA, ES:DATA
BEGIN: MOV AX, DATA
 MOV DS, AX
 MOV ES, AX

 MOV BX, 0  ; 保存当前显示方式
 MOV AH, 0FH
 INT 10H
 PUSH AX
 PUSH BX

 MOV AL, 03H  ; 置显示模式
 MOV AH, 0
 INT 10H

;********************************开始界面********************************
 
;**********显示欢迎信息（打字效果）**********

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'W'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'E'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'L'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'C'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'O'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'M'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'E'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, ' '
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'T'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'O'
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, ' '
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'T'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'H'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'E'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, ' '
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'G'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'A'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'M'
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'E'
 INT 10H
 CALL DELAY
 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, ' '
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'W'
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'O'
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'R'
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'L'
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, 'D'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, ' '
 INT 10H
 CALL DELAY

 
 MOV AH, 0EH
 MOV BH, 0
 MOV AL, '!'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, ' '
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, '^'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, '_'
 INT 10H
 CALL DELAY

 MOV AH, 0EH
 MOV BH, 0
 MOV AL, '^'
 INT 10H

; **********显示其它提示信息************

 MOV BP, OFFSET INFO
 MOV CX, 32D
 ;通过bios功能调用实现字符指定位置的打印
 ;dh表示打印的行号，dl表示打印的列
 ;下面表示info是从(0,46)处开始打印
 MOV DH, 0
 MOV DL, 46D
    
 MOV AL, 1
 MOV BL, 0BH
 MOV AH, 13H
 INT 10H


 CALL ENDLINE
 MOV AH, 09H
 MOV BH, 0
;bios功能调用实现指定字符的多次打印
;cx控制打印字符的数量
 MOV CX, 80D
 ;bl控制打印字符的颜色
 MOV BL, 02H
 ;al表示要打印的字符
 MOV AL, '*'
 ;bios系统调用处理
 INT 10H
 ;实现回车换行的打印
 CALL ENDLINE

 MOV BP, OFFSET TIPS1
 MOV CX, 12D
 MOV DH, 04H
 MOV DL, 0
 MOV AL, 03
 MOV AH, 13H
 INT 10H

 MOV BP,OFFSET CONTENT
 MOV CX, 45D
 MOV DH, 06D
 MOV DL, 17D
 MOV AL, 01
 MOV BL, 0CH
 MOV AH, 13H
 INT 10H

 CALL ENDLINE
 MOV AH, 09H
 MOV BH, 0
 MOV CX, 80D
 MOV BL, 02H
 MOV AL, '*'
 INT 10H
 CALL ENDLINE

 MOV AH, 02H
 MOV BH, 0
 MOV DH, 15D
 MOV DL, 0
 INT 10H
 MOV AH, 09H
 MOV BH, 0
 MOV CX, 80D
 MOV BL, 02H
 MOV AL, '*'
 INT 10H

; ************显示选择菜单**************

 MOV BP, OFFSET TIPS3
 MOV CX, 11D
 ;行
 MOV DH, 10D
 ;列
 MOV DL, 0
 ;写模式
 MOV AL, 01
 ;颜色
 MOV BL, 0EH
 MOV AH, 13H
 INT 10H
 CALL MODESELECT
 CMP MODEFLAG, 0
;对zf标志位进行判断来决定进入的模式
 JE GOGAME1
 ;无条件跳转
 JMP GOGAME2

GOGAME1: MOV BP, OFFSET TIPS2
 MOV CX, 17D
 MOV DH, 17D
 MOV DL, 0
 MOV AL, 03
 MOV AH, 13H
 INT 10H
 MOV AH, 02H
 MOV BH, 0
 MOV DH, 22D
 MOV DL, 0
 INT 10H
 MOV AH, 09H
 MOV BH, 0
 MOV CX, 80D
 MOV BL, 02H
 MOV AL, '*'
 INT 10H
 CALL SELECT  ; 调用难度选择菜单函数 

 MOV AH, 02H  
 MOV BH, 0
 MOV DH, 24D
 MOV DL, 25D
 INT 10H
 MOV DX, OFFSET STR1 ; 确认难度选项
 MOV AH, 09H
 INT 21H
 
 CMP DIFFICULTYFLAG, 0FFH 
 JE SHARD
 MOV AH, 13H
 MOV BL, 0EH
 MOV BH, 0
 MOV BP, OFFSET NORMAL
 MOV AL, 1
 MOV CX, 6
 MOV DH, 24D
 MOV DL, 43D
 INT 10H
 JMP NEXT1
SHARD: MOV AH, 13H
 MOV BL, 0EH
 MOV BH, 0
 MOV BP, OFFSET HARD
 MOV AL, 1
 MOV CX, 6
 MOV DH, 24D
 MOV DL, 42D
 INT 10H
NEXT1: MOV DX, OFFSET STR2
 MOV AH, 09H
 INT 21H

 MOV AH, 07H
 INT 21H
 CMP DIFFICULTYFLAG, 0  ; 根据选择难度设置延时和字符下落个数
 JE NEXT2
 MOV DELAYTIME, 01H
 MOV TOTAL, 50D
 JMP NEXT3
NEXT2: MOV DELAYTIME, 04H
 MOV TOTAL, 50D

;********************************游戏开始********************************


;设置活动显示页面
NEXT3:  MOV AH, 05H ; 置当前页为第2页
  MOV AL, 2
  INT 10H

; ******显示统计信息******
  MOV AH, 13H
  MOV BH, 2
  MOV BL, 0AH
  MOV CX, 04H
  MOV DH, 1D
  MOV DL, 50D
  MOV AL, 1
  MOV BP, OFFSET HIT
  INT 10H
  MOV AH, 13H
  MOV BH, 2
  MOV BL, 07H
  MOV CX, 05H
  MOV DH, 1D
  MOV DL, 60D
  MOV AL, 1
  MOV BP, OFFSET MISS
  INT 10H
  MOV AH, 13H
  MOV BH, 2
  MOV BL, 0DH
  MOV CX, 06H
  MOV DH, 1D
  MOV DL, 70D
  MOV AL, 1
  MOV BP, OFFSET SCORE
  INT 10H
  MOV AH, 13H
  MOV BH, 2
  MOV BL, 08H
  MOV CX, 28D
  MOV DH, 20D
  MOV DL, 26D
  MOV AL, 1
  MOV BP, OFFSET STR4
  INT 10H

  MOV AH, 02H
  MOV BH, 2
  MOV DH, 3D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 2
  MOV CX, 80D
  MOV BL, 02H
  MOV AL, '*'
  INT 10H
  MOV AH, 02H
  MOV BH, 2
  MOV DH, 17D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 2
  MOV CX, 80D
  MOV BL, 02H
  MOV AL, '*'
  INT 10H

;**********MODE1主循环***********

MAINLOP: CALL SETPOS
    ;调用子过程，用来决定下落哪一个字母
  CALL WHICHONE
  MOV BP, OFFSET LIST
  MOV BX, 0
    
  MOV BL, WHICH
  ADD BP, BX
  MOV CX, 1
  MOV BH, 2  ; 2号页为MODE1游戏主窗口
  MOV DH, 05H
  MOV DL, POSITION
  MOV AL, 1
  MOV BL, 0EH
  MOV AH, 13H
  INT 10H
  CALL DOWN
  MOV BL, TOTAL  ; 判定是否达到下落字符总数
  DEC BL
  MOV TOTAL, BL
  CMP TOTAL, 0
  JE TONGJI
  JMP MAINLOP
; **********显示MODE1评价画面**********  使用4号页面
TONGJI:  MOV AH, 05H
  MOV AL, 04H
  INT 10H

  MOV AH, 02H
  MOV BH, 4
  MOV DH, 14D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 4
  MOV CX, 80D
  MOV BL, 05H
  MOV AL, '*'
  INT 10H
  MOV AH, 02H
  MOV BH, 4
  MOV DH, 18D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 4
  MOV CX, 80D
  MOV BL, 05H
  MOV AL, '*'
  INT 10H
  MOV AH, 13H
  MOV BH, 4
  MOV BL, 0EH
  MOV CX, 28D
  MOV DH, 16D
  MOV DL, 26D
  MOV AL, 1
  MOV BP, OFFSET STR3
  INT 10H
  MOV AH, 02H
  MOV BH, 4
  MOV DH, 16D
  MOV DL, 53D
  INT 10H
  MOV AH, 02H
  MOV BH, 4
  MOV DH, 16D
  MOV DL, 55D
  INT 10H
  CMP SCORENUMBER, 90D ; 评价标准
  JA NEXT4
  CMP SCORENUMBER, 80D
  JA NEXT5
  CMP SCORENUMBER, 70D
  JA NEXT6
  CMP SCORENUMBER, 60D
  JA NEXT7
  MOV AL, 'D'
  MOV BH, 4
  MOV BL, 0CH
  MOV CX, 1
  MOV AH, 09H
  INT 10H
  JMP NEXT8
NEXT4:  MOV AL, 'S'
  MOV BH, 4
  MOV BL, 0CH
  MOV CX, 1
  MOV AH, 09H
  INT 10H
  JMP NEXT8
NEXT5:  MOV AL, 'A'
  MOV BH, 4
  MOV BL, 0CH
  MOV CX, 1
  MOV AH, 09H
  INT 10H
  JMP NEXT8
NEXT6:  MOV AL, 'B'
  MOV BH, 4
  MOV BL, 0CH
  MOV CX, 1
  MOV AH, 09H
  INT 10H
  JMP NEXT8
NEXT7:  MOV AL, 'C'
  MOV BH, 4
  MOV BL, 0CH
  MOV CX, 1
  MOV AH, 09H
  INT 10H
  JMP NEXT8

NEXT8:  MOV AH, 13H
  MOV BL, 0CH
  MOV BH, 4
  MOV BP, OFFSET THANKS
  MOV AL, 1
  MOV CX, 26D
  MOV DH, 22D
  MOV DL, 45D
  INT 10H
  MOV AH, 13H
  MOV BL, 07H
  MOV BH, 4
  MOV BP, OFFSET JIESHU
  MOV AL, 1
  MOV CX, 25D
  MOV DH, 23D
  MOV DL, 50D
  INT 10H
  MOV AH, 07H
  INT 21H
  MOV AH, 07H
  INT 21H
  JMP OVER

;*******************MODE2游戏主程序*********************

GOGAME2: MOV AH, 02H
  MOV BH, 0
  MOV DH, 20D
  MOV DL, 45D
  INT 10H
  
  MOV DX, OFFSET STR2
  MOV AH, 09H
  INT 21H
  MOV AH, 07H
  INT 21H

  MOV AH, 05H  ; 5号页为MODE2游戏页面
  MOV AL, 5D
  INT 10H
  MOV AH, 02H
  MOV BH, 5D
  MOV DH, 04D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 5D
  MOV CX, 80D
  MOV BL, 02H
  MOV AL, '*'
  INT 10H
  MOV AH, 02H
  MOV BH, 5D
  MOV DH, 12D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 5D
  MOV CX, 80D
  MOV BL, 08H
  MOV AL, '-'
  INT 10H
  MOV AH, 02H
  MOV BH, 5D
  MOV DH, 20D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 5D
  MOV CX, 80D
  MOV BL, 02H
  MOV AL, '*'
  INT 10H
  MOV BP, OFFSET TIPS4
  MOV BH, 05H
  MOV CX, 54D
  MOV DH, 22D
  MOV DL, 13D
  MOV BL, 0CH
  MOV AL, 01H
  MOV AH, 13H
  INT 10H
  MOV BP, OFFSET TIPS5
  MOV BH, 05H
  MOV CX, 17D
  MOV DH, 23D
  MOV DL, 55D
  MOV BL, 0AH
  MOV AL, 01H
  MOV AH, 13H
  INT 10H

  MOV BP, OFFSET ARTICLE
  MOV BH, 05H
  MOV CX, 200D
  MOV DH, 07D
  MOV DL, 0
  MOV AL, 01H
  MOV BL, 0EH
  MOV AH, 13H
  INT 10H
  MOV AH, 02H
  MOV BH, 5D
  MOV DH, 15D
  MOV DL, 0
  INT 10H
  MOV SI, OFFSET ARTICLE
  MOV AH, 2CH
  INT 21H
  MOV MINUTE, CL
  MOV SECOND, DH
  MOV HOUR, CH   ; 存储计算所得的结果（当前时间换算成秒的总和）
  
TYPELOP: CALL TYPESTART
  JMP TYPELOP

;**********显示MODE2评价画面**********(使用7号页面）


PINGJIA: MOV AH, 05H
  MOV AL, 07H
  INT 10H

  MOV AH, 13H
  MOV BH, 7
  MOV BL, 0EH
  MOV CX, 28D
  MOV DH, 12D
  MOV DL, 05D
  MOV AL, 1
  MOV BP, OFFSET STR3
  INT 10H
  MOV AH, 13H  ; 结束信息
  MOV BL, 0CH
  MOV BH, 07H
  MOV BP, OFFSET THANKS
  MOV AL, 1
  MOV CX, 26D
  MOV DH, 21D
  MOV DL, 45D
  INT 10H
  MOV AH, 13H
  MOV BL, 07H
  MOV BH, 07H
  MOV BP, OFFSET JIESHU
  MOV AL, 1
  MOV CX, 25D
  MOV DH, 23D
  MOV DL, 50D
  INT 10H

  MOV AH, 02H
  MOV BH, 7
  MOV DH, 14D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 7
  MOV CX, 80D
  MOV BL, 05H
  MOV AL, '*'
  INT 10H
  MOV AH, 02H
  MOV BH, 7
  MOV DH, 18D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 7
  MOV CX, 80D
  MOV BL, 05H
  MOV AL, '*'
  INT 10H
  MOV BP, OFFSET STR5
  MOV BH, 7
  MOV CX, 12D
  MOV DH, 16D
  MOV DL, 5D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 07H
  INT 10H

;***********显示出开始打字的时间************

  MOV AX, 0
  MOV AL, HOUR
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 18D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H
  MOV AL, ':'
  MOV BH, 7D
  MOV CX, 01H
  MOV BL, 0EH
  MOV AH, 09H
  INT 10H
  MOV AX, 0
  MOV AL, MINUTE
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 21D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H
  MOV AL, ':'
  MOV BH, 7D
  MOV CX, 01H
  MOV BL, 0EH
  MOV AH, 09H
  INT 10H
  MOV AX, 0
  MOV AL, SECOND
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 24D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H

  MOV BP, OFFSET STR7
  MOV BH, 7
  MOV CX, 9
  MOV DH, 16D
  MOV DL, 32D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 07H
  INT 10H

  MOV AH, 2CH  ; 获取当前时间
  INT 21H
  MOV HOUR, CH
  MOV MINUTE, CL
  MOV SECOND, DH

;***********显示出打字结束的时间************

  MOV AX, 0
  MOV AL, HOUR
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 42D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H
  MOV AL, ':'
  MOV BH, 7D
  MOV CX, 01H
  MOV BL, 0EH
  MOV AH, 09H
  INT 10H
  MOV AX, 0
  MOV AL, MINUTE
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 45D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H
  MOV AL, ':'
  MOV BH, 7D
  MOV CX, 01H
  MOV BL, 0EH
  MOV AH, 09H
  INT 10H
  MOV AX, 0
  MOV AL, SECOND
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 48D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H

  MOV BP, OFFSET STR6
  MOV BH, 7
  MOV CX, 10D
  MOV DH, 16D
  MOV DL, 60D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 07H
  INT 10H

;*******************显示命中******************
  MOV AX, 0
  MOV AL, HITNUMBER
  CMP AL, 200D
  JB HITNEXT
  JMP HITMAX
HITNEXT: MOV BX, 0
  MOV BL, 2  ; 求正确率，因为是200个字母，所以将正确敲击的字母个数除以2
  DIV BL   ; 商在AL余数在AH
  MOV HITNUMBER, AL
  MOV CH, AH  ; 暂存AH
  MOV AX, 0
  MOV AL, HITNUMBER
  MOV HITNUMBER, CH ; 取出余数
  MOV DI, OFFSET TEMP
  INC DI
  MOV DX, 0
  MOV BX, 10D
  DIV BX
  XCHG AX, DX
  ADD AL, 30H
  MOV [DI], AL
  DEC DI
  ADD DL, 30H
  MOV [DI], DL
  MOV BP, OFFSET TEMP
  MOV BH, 7
  MOV CX, 2
  MOV DH, 16D
  MOV DL, 70D
  MOV AL, 01H
  MOV AH, 13H
  MOV BL, 0EH
  INT 10H
  MOV AL, HITNUMBER
  CMP AL, 0
  JNZ DISPNEXT
  JMP NODISP  ; 如果正确的个数为奇数个，则后面加".5"
DISPNEXT: MOV AH, 09H
  MOV CX, 1
  MOV BH, 07H
  MOV BL, 0EH
  MOV AL, '.'
  INT 10H
  
  MOV AH, 02H
  MOV BH, 07H
  MOV DH, 16D
  MOV DL, 73D
  INT 10H

  MOV AH, 09H
  MOV BH, 07H
  MOV CX, 1
  MOV BL, 0EH
  MOV AL, '5'
  INT 10H

NODISP:  MOV AH, 02H
  MOV BH, 07H
  MOV DH, 16D
  MOV DL, 74D
  INT 10H
  MOV DL, '%'
  MOV AH, 02H
  INT 21H
  JMP HITOVER

  
  
HITMAX:  MOV BP, OFFSET MAX
  MOV BH, 07H
  MOV DH, 16D
  MOV DL, 70D
  MOV CX, 5
  MOV AL, 1
  MOV BL, 0EH
  MOV AH, 13H
  INT 10H

HITOVER:  MOV AH, 07H
   INT 21H
   MOV AH, 07H
   INT 21H

;*************结束部分**************

OVER:  POP BX   ; 恢复原始参数
  POP AX
  MOV AH, 0  ; 恢复原始显示模式
  INT 10H
  MOV AH, 4CH
  INT 21H

;****************以下是子程序部分*****************

SETPOS PROC    ; 用来产生字母随机的起始位置
 MOV AH, 2CH   ; 获取系统时间
 INT 21H
 MOV AX, 0
 MOV AL, DL   ; 将时间（1/100秒单位）除以80取余获得随机数
 MOV BL, 80D 
 DIV BL
 MOV POSITION, AH
 RET
SETPOS  ENDP


WHICHONE PROC    ; 用来决定下落哪一个字母
 MOV AH, 2CH
 INT 21H    ; 获取系统时间
 MOV AX, 0
 MOV AL, DL
 MOV BL, 26D   ; 将时间（1/100秒单位）除以26取余获得随机数
 DIV BL
 MOV WHICH, AH
 RET
WHICHONE ENDP


SELECT PROC    ; 难度选择菜单
SELECTLOP1: CMP DIFFICULTYFLAG, 0FFH ; 判定当前选项
  JE SELECTLOP2   
  MOV AH, 06H
  MOV AL, 0
  MOV BH, 07H
  MOV CH, 18D
  MOV CL, 0
  MOV DH, 19D
  MOV DL, 79
  INT 10H

;******NORMAL被选中*********

  MOV AH, 13H
  MOV BL, 9EH
  MOV BH, 0
  MOV BP, OFFSET NORMAL
  MOV AL, 1
  MOV CX, 6
  MOV DH, 18D
  MOV DL, 36D
  INT 10H
  MOV AH, 13H
  MOV BL, 08H
  MOV BH, 0
  MOV BP, OFFSET HARD
  MOV AL, 1
  MOV CX, 6
  MOV DH, 19D
  MOV DL, 36D
  INT 10H
  JMP SELECTNEXT

;********HARD被选中*********

SELECTLOP2: MOV AH, 06H
  MOV AL, 0
  MOV BH, 07H
  MOV CH, 18D
  MOV CL, 0
  MOV DH, 19D
  MOV DL, 79
  INT 10H

  MOV AH, 13H
  MOV BL, 08H
  MOV BH, 0
  MOV BP, OFFSET NORMAL
  MOV AL, 1
  MOV CX, 6
  MOV DH, 18D
  MOV DL, 36D
  INT 10H
  MOV AH, 13H
  MOV BL, 9EH
  MOV BH, 0
  MOV BP, OFFSET HARD
  MOV AL, 1
  MOV CX, 6
  MOV DH, 19D
  MOV DL, 36D
  INT 10H

SELECTNEXT: MOV AH, 00  ; 获取输入
  INT 16H
  CMP AH,48H  ; 上箭头
  JE SELECTRESET  ; 反向
  CMP AH,50H  ; 下箭头
  JE SELECTRESET
  CMP AH,1CH  ; 回车
  JNE SELECTNEXT  ; 输入非法
  RET
SELECTRESET: NOT DIFFICULTYFLAG ; 标志各位取反 
  JMP SELECTLOP1
SELECT ENDP

 

MODESELECT PROC    ; MODE选择菜单
MODESELECTLOP1: CMP MODEFLAG, 0FFH ; 判定当前选项
  JE MODESELECTLOP2   
  MOV AH, 06H
  MOV AL, 0
  MOV BH, 07H
  MOV CH, 12D
  MOV CL, 0
  MOV DH, 13D
  MOV DL, 79
  INT 10H

  MOV AH, 13H
  MOV BL, 9EH
  MOV BH, 0
  MOV BP, OFFSET MODE1
  MOV AL, 1
  MOV CX, 5
  MOV DH, 12D
  MOV DL, 32D
  INT 10H
  MOV AH, 13H
  MOV BL, 08H
  MOV BH, 0
  MOV BP, OFFSET MODE2
  MOV AL, 1
  MOV CX, 5
  MOV DH, 12D
  MOV DL, 41D
  INT 10H
  JMP MODESELECTNEXT

MODESELECTLOP2: 
;向上滚动的窗口
  MOV AH, 06H
  ;滚动的行
  MOV AL, 0
  ;背景颜色
  MOV BH, 07H
  ;高行数
  MOV CH, 18D
    ;左列数
  MOV CL, 0
  ;低行数，右列数
  MOV DH, 19D
  MOV DL, 79
  INT 10H
    
  MOV AH, 13H
  MOV BL, 08H
  MOV BH, 0
  MOV BP, OFFSET MODE1
  MOV AL, 1
  MOV CX, 5
  MOV DH, 12D
  MOV DL, 32D
  INT 10H
  MOV AH, 13H
  MOV BL, 9EH
  MOV BH, 0
  MOV BP, OFFSET MODE2
  MOV AL, 1
  MOV CX, 5
  MOV DH, 12D
  MOV DL, 41D
  INT 10H

MODESELECTNEXT: MOV AH, 00  ; 获取输入
  INT 16H

  CMP AH,4BH  ; Z箭头
  JE MODESELECTRESET ; 反向
  CMP AH,4DH  ; Y箭头
  JE MODESELECTRESET
  CMP AH,1CH  ; 回车
  JNE MODESELECTNEXT ; 输入非法
  RET
  ;将操作数按位取反
MODESELECTRESET: NOT MODEFLAG ; 标志各位取反 
  JMP MODESELECTLOP1
MODESELECT ENDP

 

DOWN PROC    ; 控制字符下落
  MOV HANGID, 5  ; 从第五行开始下落
DOWNLOP: CALL REFRESH  ; 刷新成绩统计函数  

  MOV AH, 01H  ; 检测键盘是否有按键输入
  INT 16H
  ;通过判断zf标志位，决定是否跳转
  ;zf为1则跳转，即用户没有输入
  JZ DOWNCONTINUE
;有输入就读取输入的信息   
  MOV AH, 0  ; 如果有，则读取
    ;获取键盘输入的中断
  INT 16H

  MOV BX, 0
  MOV BL, 41H  ; A的ASCII码
  MOV BH, 61H  ; a的ASCII码
  ADD BL, WHICH  ; 获取当前字符的ASCII码（BL中为大写，BH中为小写）
  ADD BH, WHICH  
  CMP BL, AL  ; 比较当前读入的ASCII码与下落中的字符是否相同
  JE DOWNNEXT1
  CMP BH, AL
  JE DOWNNEXT1
  CMP AH, 01H  ;　如果按键为ESC，则显示退出菜单
  JNE DOWNCONTINUE
  CALL EXITMENU
  CMP OUTFLAG, 0 
  JE DOWNCONTINUE2

  MOV AH, 13H  ; 结束信息
  MOV BL, 0CH
  MOV BH, 3
  MOV BP, OFFSET THANKS
  MOV AL, 1
  MOV CX, 26D
  MOV DH, 18D
  MOV DL, 45D
  INT 10H
  MOV AH, 13H
  MOV BL, 07H
  MOV BH, 3
  MOV BP, OFFSET JIESHU
  MOV AL, 1
  MOV CX, 25D
  MOV DH, 19D
  MOV DL, 50D
  INT 10H
  MOV AH, 07H
  INT 21H
  JMP OVER

DOWNCONTINUE2: MOV AH, 05H
  MOV AL, 02H
  INT 10H
DOWNCONTINUE: MOV CH, 5D
  MOV CL, 0
  MOV DH, 15D
  MOV DL, 79D
  MOV BX, 0
  MOV AH, 07H
  MOV AL, 01H
  INT 10H
  CALL DELAY
  MOV BL, HANGID  ; 每下落一行HANGID递增1（跟踪字符位置）
  INC BL
  MOV HANGID, BL
  MOV BL, HANGID
  CMP BL, 17D  ; 若下落到15行，调用函数，使字符消失
  JA DOWNNEXT2
  JMP DOWNLOP
DOWNNEXT1: MOV BX, 0
  MOV BL, SCORENUMBER
  INC BL
  INC BL
  MOV SCORENUMBER, BL
  MOV BH, HITNUMBER
  INC BH
  MOV HITNUMBER, BH
  CALL DISPEAR  ; 判定为用户按键消除，则HITNUMBER,SCORENUMBER都增加
  JMP DOWNOVER
DOWNNEXT2: MOV BX, 0
  MOV BL, MISSNUMBER
  INC BL
  MOV MISSNUMBER, BL
  CALL DISPEAR  ; 判定字符到底部被动消除，则MISSNUMBER增加
DOWNOVER: RET
DOWN ENDP


DELAY PROC    ; 延时函数
 MOV AH, 0
 INT 1AH    ; 直接读取时钟计数器
 MOV BX, DX
 MOV AX, 0
 MOV AL, DELAYTIME  ; 加上DELAY间隔
 ADD BX, AX
DELAYLOP: MOV AH, 0
  INT 1AH
  CMP DX, BX
  JE DELAYNEXT
  JMP DELAYLOP
DELAYNEXT: RET
DELAY ENDP


DISPEAR PROC    ; 消除函数
 MOV BP, OFFSET BLANK  ; 实质是在当前字符所在位置写入空格，覆盖原字符
 ;字符的长度
 MOV CX, 1
 MOV BH, 2 ;2号页
 ;获取当前字符所在行和列
 MOV DH, HANGID   ; 当前字符所在行
 MOV DL, POSITION  ; 当前字符所在列
 ;写模式是3
 MOV AL, 3
;写字符串的功能调用
 MOV AH, 13H
 ;bios的中断调用的第10h号功能的简写
 INT 10H
 RET
DISPEAR ENDP


EXITMENU PROC    ; 退出菜单（3号页面）
  MOV AH, 05H
  MOV AL, 03H
  INT 10H
  MOV AH, 02H
  MOV BH, 3
  MOV DH, 10D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 3
  MOV CX, 80D
  MOV BL, 02H
  MOV AL, '*'
  INT 10H
  MOV AH, 02H
  MOV BH, 3
  MOV DH, 15D
  MOV DL, 0
  INT 10H
  MOV AH, 09H
  MOV BH, 3
  MOV CX, 80D
  MOV BL, 02H
  MOV AL, '*'
  INT 10H

; ********NOTQUIT被选中*********

EXITLOP1: CMP OUTFLAG, 0FFH ; 判定当前选项
  JE EXITLOP2
  MOV AH, 06H
  MOV AL, 0
  MOV BH, 07H
  MOV CH, 12D
  MOV CL, 0
  MOV DH, 13D
  MOV DL, 79
  INT 10H

  MOV AH, 13H
  MOV BL, 9EH
  MOV BH, 3
  MOV BP, OFFSET NOTQUIT  
  MOV AL, 1
  MOV CX, 18D
  MOV DH, 12D
  MOV DL, 32D
  INT 10H
  MOV AH, 13H
  MOV BL, 08H
  MOV BH, 3
  MOV BP, OFFSET YESQUIT
  MOV AL, 1
  MOV CX, 18D
  MOV DH, 13D
  MOV DL, 32D
  INT 10H
  JMP EXITNEXT

; ********YESQUIT被选中*********

EXITLOP2: MOV AH, 06H  
  MOV AL, 0
  MOV BH, 07H
  MOV CH, 12D
  MOV CL, 0
  MOV DH, 13D
  MOV DL, 79
  INT 10H

  MOV AH, 13H
  MOV BL, 08H
  MOV BH, 3
  MOV BP, OFFSET NOTQUIT  
  MOV AL, 1
  MOV CX, 18D
  MOV DH, 12D
  MOV DL, 32D
  INT 10H
  MOV AH, 13H
  MOV BL, 9EH
  MOV BH, 3
  MOV BP, OFFSET YESQUIT
  MOV AL, 1
  MOV CX, 18D
  MOV DH, 13D
  MOV DL, 32D
  INT 10H

EXITNEXT: MOV AH, 00  ; 获取输入
  INT 16H
  CMP AH,48H  ; 上箭头
  JE EXITRESET  ; 反向
  CMP AH,50H  ; 下箭头
  JE EXITRESET
  CMP AH,1CH  ; 回车
  JNE EXITNEXT  ; 输入非法
  RET
EXITRESET: NOT OUTFLAG  ;标志各位取反 
  JMP EXITLOP1
EXITMENU ENDP


ENDLINE PROC    ; 打印回车换行
 MOV DX, OFFSET ENDL
 MOV AH, 09H
 INT 21H

 MOV DX, OFFSET ENDL
 MOV AH, 09H
 INT 21H
 RET
ENDLINE ENDP

REFRESH PROC    ; 刷新成绩统计
 
;******将各个统计计数（16进制）除10取余转化为10进制数，并存入TEMP中,在相应位置写入TEMP中存储的数字
 
 MOV AX, 0
 MOV AL, HITNUMBER  
 MOV DI, OFFSET TEMP
 INC DI
 MOV DX, 0
 MOV BX, 10D
 DIV BX
 XCHG AX, DX
 ADD AL, 30H
 MOV [DI], AL
 DEC DI
 ADD DL, 30H
 MOV [DI], DL
 MOV BP, OFFSET TEMP
 MOV BH, 02H
 MOV CX, 2
 MOV DH, 1D
 MOV DL, 55D
 MOV AL, 01H
 MOV AH, 13H
 MOV BL, 0EH
 INT 10H
 
 MOV AX, 0
 MOV AL, MISSNUMBER
 MOV DI, OFFSET TEMP
 INC DI
 MOV DX, 0
 MOV BX, 10D
 DIV BX
 XCHG AX, DX
 ADD AL, 30H
 MOV [DI], AL
 DEC DI
 ADD DL, 30H
 MOV [DI], DL
 MOV BP, OFFSET TEMP
 MOV BH, 02H
 MOV CX, 2
 MOV DH, 1D
 MOV DL, 66D
 MOV AL, 01H
 MOV AH, 13H
 MOV BL, 0EH
 INT 10H
 
 MOV AX, 0
 MOV AL, SCORENUMBER
 MOV DI, OFFSET TEMP
 INC DI
 MOV DX, 0
 MOV BX, 10D
 DIV BX
 XCHG AX, DX
 ADD AL, 30H
 MOV [DI], AL
 DEC DI
 ADD DL, 30H
 MOV [DI], DL
 MOV BP, OFFSET TEMP
 MOV BH, 02H
 MOV CX, 2
 MOV DH, 1D
 MOV DL, 77D
 MOV AL, 01H
 MOV AH, 13H
 MOV BL, 0EH
 INT 10H
 RET
REFRESH ENDP


TYPESTART PROC   ; MODE2模式主要工作函数
 MOV AH, 01H
 INT 21H
 CMP AL, 1BH  ;　如果按键为ESC，则直接退出
 JNE NOESC

 MOV AH, 05H
 MOV AL, 06H  ; 6号页面作为MODE2退出画面
 INT 10H
 MOV AH, 13H  ; 结束信息
 MOV BL, 0CH
 MOV BH, 06H
 MOV BP, OFFSET THANKS
 MOV AL, 1
 MOV CX, 26D
 MOV DH, 18D
 MOV DL, 45D
 INT 10H
 MOV AH, 13H
 MOV BL, 07H
 MOV BH, 06H
 MOV BP, OFFSET JIESHU
 MOV AL, 1
 MOV CX, 25D
 MOV DH, 19D
 MOV DL, 50D
 INT 10H
 MOV AH, 07H
 INT 21H
 JMP OVER

NOESC: MOV BL, [SI]
 CMP AL, BL
 JNE TYPEWRONG
 MOV BL, HITNUMBER
 INC BL
 MOV HITNUMBER, BL
TYPEWRONG:  MOV BL, TOTAL
   INC BL
   MOV TOTAL, BL
   CMP BL, 200D
   JNE TYPENEXT
   JMP PINGJIA 
TYPENEXT:  INC SI
   RET
TYPESTART ENDP

CODE ENDS
END BEGIN

